<!DOCTYPE html>
<html lang="en">

<!-- Head tag -->
<head><meta name="generator" content="Hexo 3.8.0">

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!--Description-->

    

    
        <meta name="description" content="在看本文之前， 可以先看一下上一篇关于rtmp的文章：http://www.cyrus.fun/2019/08/06/RTMP协议解析/
FLV文件结构首先，看一下flv文件结构:用软件看:

FLV文件由FLV header 和FVL Body组成；
FLV Body由一系列Tag组成，Tag分为">
    

    <!--Author-->
    
        <meta name="author" content="Cyrus">
    

    <!--Open Graph Title-->
    
        <meta property="og:title" content="FLV文件格式解析（h264 + aac）">
    

    <!--Open Graph Description-->
    
        <meta property="og:description" content="在看本文之前， 可以先看一下上一篇关于rtmp的文章：http://www.cyrus.fun/2019/08/06/RTMP协议解析/
FLV文件结构首先，看一下flv文件结构:用软件看:

FLV文件由FLV header 和FVL Body组成；
FLV Body由一系列Tag组成，Tag分为">
    

    <!--Open Graph Site Name-->
        <meta property="og:site_name" content="Cyrus的技术空间">

    <!--Type page-->
    
        <meta property="og:type" content="article">
    

    <!--Page Cover-->
    
    
        <meta property="og:image" content="http://cyrus_huang.gitee.io/bloghttp://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg">
    

        <meta name="twitter:card" content="summary_large_image">

    

    
        <meta name="twitter:image" content="http://cyrus_huang.gitee.io/bloghttp://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg">
    

    <!-- Title -->
    
    <title>FLV文件格式解析（h264 + aac） - Cyrus的技术空间</title>

    <!-- Bootstrap Core CSS -->
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/blog/css/style.css">

    <!-- Custom Fonts -->
    <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css">
    <link href="//fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic" rel="stylesheet" type="text/css">
    <link href="//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">

    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

    <!-- Gallery -->
    <link href="//cdnjs.cloudflare.com/ajax/libs/featherlight/1.3.5/featherlight.min.css" type="text/css" rel="stylesheet">

    <!-- Google Analytics -->
    


    <!-- favicon -->
    

</head>


<body>

    <!-- Menu -->
    <!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="/blog/">Cyrus的技术空间</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav navbar-right">
                
                    <li>
                        <a href="/blog/">
                            
                                Home
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/archives">
                            
                                Archives
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/tags">
                            
                                Tags
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="/blog/categories">
                            
                                Categories
                            
                        </a>
                    </li>
                
                    <li>
                        <a href="https://github.com/klugjo/hexo-theme-clean-blog">
                            
                                <i class="fa fa-github fa-stack-2x"></i>
                            
                        </a>
                    </li>
                
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
</nav>

    <!-- Main Content -->
    <!-- Page Header -->
<!-- Set your background image for this header in your post front-matter: cover -->

<header class="intro-header" style="background-image: url('http://www.codeblocq.com/assets/projects/hexo-theme-clean-blog/img/home-bg.jpg')">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <div class="post-heading">
                    <h1>FLV文件格式解析（h264 + aac）</h1>
                    
                    <span class="meta">
                        <!-- Date and Author -->
                        
                            Posted by Cyrus on
                        
                        
                            2019-08-08
                        
                    </span>
                </div>
            </div>
        </div>
    </div>
</header>

<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">

            <!-- Tags and categories -->
           
                <div class="col-lg-4 col-lg-offset-2 col-md-5 col-md-offset-1 post-tags">
                    
                        


<a href="/blog/tags/FLV/">#FLV</a>


                    
                </div>
                <div class="col-lg-4 col-md-5 post-categories">
                    
                        

<a href="/blog/categories/音视频/">音视频</a>

                    
                </div>
            

            <!-- Gallery -->
            

            <!-- Post Main Content -->
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <p>在看本文之前， 可以先看一下上一篇关于rtmp的文章：<br><a href="http://www.cyrus.fun/2019/08/06/RTMP协议解析/" target="_blank" rel="noopener">http://www.cyrus.fun/2019/08/06/RTMP协议解析/</a></p>
<h3 id="FLV文件结构"><a href="#FLV文件结构" class="headerlink" title="FLV文件结构"></a>FLV文件结构</h3><p>首先，看一下flv文件结构:<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/flv_1.png" alt=""><br>用软件看:<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/flv_2.png" alt=""></p>
<ul>
<li>FLV文件由FLV header 和FVL Body组成；</li>
<li>FLV Body由一系列Tag组成，Tag分为Tag header 和Tag body两部分。</li>
<li>每个Tag后面有四个长节的长度，为之前Tag的Tag header + Tag body的大小。</li>
</ul>
<h3 id="FLV-header-9-byts"><a href="#FLV-header-9-byts" class="headerlink" title="FLV header(9 byts)"></a>FLV header(9 byts)</h3><p><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/flv_header.png" alt=""></p>
<ul>
<li>前三个字节为‘FLV’</li>
<li>第四个字节为 Version </li>
<li>第五个字节分为4部分，<ul>
<li>前5bit为保留字节，为0</li>
<li>第6bit 是否包含音频</li>
<li>第7bit 保留 0</li>
<li>第8bit 是否包含视频</li>
</ul>
</li>
<li>4字节 DataOffset，即header长度，Version为1长度为9</li>
</ul>
<h3 id="FLV-body"><a href="#FLV-body" class="headerlink" title="FLV body"></a>FLV body</h3><p>flv body部分是一系统的tag，主要分为三种script tag, video tag, audio tag<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/tag_1.png" alt=""><br>Tag 分为 tag header 和 tag data，</p>
<ul>
<li>tag header与rtmp header类似</li>
<li>tag data 则与rtmp body一致</li>
</ul>
<h4 id="FLV-Tag-Header-结构"><a href="#FLV-Tag-Header-结构" class="headerlink" title="FLV Tag Header 结构"></a>FLV Tag Header 结构</h4><p>FLV Tag header 与 rtmp header对比，tag type与rtmp一致，主要是0x12(script), 0x08(audio), 0x09(video)<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/tag_2.png" alt=""></p>
<h3 id="Script-tag"><a href="#Script-tag" class="headerlink" title="Script tag"></a>Script tag</h3><p>Script tag， 第一个tag，包含文件meta data，一般只出现一次<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/script.png" alt=""><br>Type id(0x12)<br>Tag Data 参考上一篇rtmp amf解析<br>这里说一下 AMF type 8(array)的解析<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">08 type 8(array)</span><br><span class="line">00 00 00 10 (metadata count 16)</span><br><span class="line">… 与AMF type 3(object)解析一致[string: any]</span><br><span class="line">00 00 09 结束标致</span><br></pre></td></tr></table></figure></p>
<h3 id="video-tag"><a href="#video-tag" class="headerlink" title="video tag"></a>video tag</h3><h4 id="Sps-pps"><a href="#Sps-pps" class="headerlink" title="Sps/pps"></a>Sps/pps</h4><p>Sps/pps, 第一个video tag,一般只出现一次<br><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/sps.png" alt=""></p>
<ul>
<li>Type id = 0x09</li>
<li>Body 前两字节为 17 00 与rtmp一致</li>
</ul>
<h4 id="I帧"><a href="#I帧" class="headerlink" title="I帧"></a>I帧</h4><p><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/I帧.png" alt=""></p>
<ul>
<li>Type id = 0x09</li>
<li>Body 前两字节为 17 01 与rtmp一致</li>
</ul>
<h4 id="B-P帧"><a href="#B-P帧" class="headerlink" title="B/P帧"></a>B/P帧</h4><p><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/B帧.png" alt=""></p>
<ul>
<li>Type id = 0x09</li>
<li>Body 前两字节为 27 01 与rtmp一致</li>
</ul>
<h3 id="audio-tag"><a href="#audio-tag" class="headerlink" title="audio tag"></a>audio tag</h3><h4 id="AAC-sequence参数"><a href="#AAC-sequence参数" class="headerlink" title="AAC sequence参数"></a>AAC sequence参数</h4><p><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/aac_1.png" alt=""></p>
<ul>
<li>Type id = 0x08</li>
<li>Body 前两字节为 af 00 与rtmp一致</li>
</ul>
<h4 id="AAC-raw-data"><a href="#AAC-raw-data" class="headerlink" title="AAC raw data"></a>AAC raw data</h4><p><img src="http://cyrus_huang.gitee.io/blog/2019/08/08/FLV文件格式解析（h264-aac）/aac_2.png" alt=""></p>
<ul>
<li>Type id = 0x08</li>
<li>Body 前两字节为 af 01 与rtmp一致</li>
</ul>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>rtmp流保存为FLV文件步骤<br>1、写入flv header, 第5字节暂存为0x00<br>2、对接收到的rtmp流数据，修改rtmp header为flv tag header(简单调换下位置)写入flv 文件，rtmp body直接不作更改写入文件，写入4字节rtmp header+rtmp body 数据长度<br>3、保存文件时，根据接收过程是否有视频流和音频流，修改flv header第5字节的值</p>


                
            </div>

            <!-- Comments -->
            
                <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                    


                </div>
            
        </div>
    </div>
</article>

    <!-- Footer -->
    <hr>

<!-- Footer -->
<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
                <ul class="list-inline text-center">
                    

                    

                    
                        <li>
                            <a href="https://github.com/klugjo/hexo-theme-clean-blog" target="_blank">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                                </span>
                            </a>
                        </li>
                    

                    

                    

                    
                </ul>
                <p class="copyright text-muted">&copy; 2020 Cyrus<br></p>
                <p class="copyright text-muted">Original Theme <a target="_blank" href="http://startbootstrap.com/template-overviews/clean-blog/">Clean Blog</a> from <a href="http://startbootstrap.com/" target="_blank">Start Bootstrap</a></p>
                <p class="copyright text-muted">Adapted for <a target="_blank" href="https://hexo.io/">Hexo</a> by <a href="http://www.codeblocq.com/" target="_blank">Jonathan Klughertz</a></p>
                <p class="copyright text-muted"><a href="http://www.beian.miit.gov.cn">粤ICP备18110122号-1</a></p>
            </div>
        </div>
    </div>
</footer>


    <!-- After footer scripts -->
    
<!-- jQuery -->
<script src="//code.jquery.com/jquery-2.1.4.min.js"></script>

<!-- Bootstrap -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

<!-- Gallery -->
<script src="//cdnjs.cloudflare.com/ajax/libs/featherlight/1.3.5/featherlight.min.js" type="text/javascript" charset="utf-8"></script>

<!-- Disqus Comments -->



</body>

</html>